package _stack_queue

import org.junit.Assert
import org.junit.Test
import kotlin.collections.ArrayDeque

/**
 * LinkedList 可以作为栈或队列使用。
 * https://www.runoob.com/java/java-linkedlist.html
 */
class TestArrayQueue_Kotlin {
    @Test
    fun test_1() {
        // add item
        // 1 2 3 =>
        val deque: ArrayDeque<Int> = ArrayDeque<Int>()
        deque.addLast(1)
        Assert.assertEquals("[1]", deque.toString())

        deque.addLast(2)
        Assert.assertEquals("[1, 2]", deque.toString())

        deque.add(3) // == addLast
        Assert.assertEquals("[1, 2, 3]", deque.toString())

        deque.addFirst(4)
        Assert.assertEquals("[4, 1, 2, 3]", deque.toString())

        // get
        // get the first value
        Assert.assertEquals(4, deque.first())
        Assert.assertEquals("[4, 1, 2, 3]", deque.toString())

        Assert.assertEquals(3, deque.last())
        Assert.assertEquals("[4, 1, 2, 3]", deque.toString())

        // index of
        Assert.assertEquals(0, deque.indexOf(4))
        Assert.assertEquals(0, deque.lastIndexOf(4))

        // delete item
        val actual2 = deque.removeFirst()  // remove the first, and return the removed value
        Assert.assertEquals(4, actual2)
        Assert.assertEquals("[1, 2, 3]", deque.toString())

        val actual3 = deque.removeLast()  // remove the last, and return the removed value
        Assert.assertEquals(3, actual3)
        Assert.assertEquals("[1, 2]", deque.toString())

        val actual4 = deque.remove(100)  // remove the target, and return the bool for success or not
        Assert.assertEquals(false, actual4)
        Assert.assertEquals("[1, 2]", deque.toString())

        Assert.assertEquals(2, deque.size)
    }

    @Test
    fun test_stack() {
        val stack: ArrayDeque<Int> = ArrayDeque<Int>()

        // 1]
        stack.addFirst(1)
        Assert.assertEquals("[1]", stack.toString())

        // 2 1]
        stack.addFirst(2)
        Assert.assertEquals("[2, 1]", stack.toString())

        Assert.assertEquals(2, stack.first())
        // 1 ]
        Assert.assertEquals(2, stack.removeFirst())
        Assert.assertEquals("[1]", stack.toString())
    }

    @Test
    fun test_queue() {
        val queue: ArrayDeque<Int> = ArrayDeque<Int>()

        //  < - 1
        queue.addLast(1)
        Assert.assertEquals("[1]", queue.toString())

        // < - 1 2
        queue.addLast(2)
        Assert.assertEquals("[1, 2]", queue.toString())

        Assert.assertEquals(1, queue.first())

        // 2 ]
        Assert.assertEquals(1, queue.removeFirst())
        Assert.assertEquals("[2]", queue.toString())
    }
}